<?php
declare (strict_types = 1);

namespace app\http;
use app\common\model\AmountLog;
use app\common\model\User;
use app\common\model\UserChat;
use app\common\model\UserMessage;
use app\common\model\Config;
use think\worker\Server;
use think\cache\driver\Redis;


class Worker extends Server
{
    protected $socket = 'websocket://0.0.0.0:2346';
    protected static $heartbeat_time = 50;



    protected $option = [
        'transport' => 'ssl',   //设置transport开启ssl，启用wss://
    ];
    public function onMessage($connection, $data)
    {
        $array  = json_decode($data,true);
        $redis  = new Redis();
        $messageUserClient = $redis->get('message_'.$array['from'].'_'.$array['to']);
        $userModel = new User();
        $userMessageModel = new UserMessage();
        if (isset( $array['from'])){
            $userInfo = $userModel->where(['id' => $array['from']])->find();
            $every_day_free_chat  = Config::getConfigValue('every_day_free_chat');
            $count  = $userMessageModel->where(['send_uid' =>  $array['from']])->where('create_time','>',strtotime(date('Y-m-d')))->count();
            $chat_price = 0;
            $original_price = $chat_price;
            $chat_level_discount = 0;
            if ($count >=  $every_day_free_chat ){
                $chat_price  = Config::getConfigValue('chat_price');
                $original_price =$chat_price;
                if ($chat_price> 0){
                    if ($userInfo['level_id'] > 1){
                        $chat_level_discount  = Config::getConfigValue('chat_level_discount');
                        if ($chat_level_discount>0){
                            $chat_price = bcdiv(bcmul($chat_price,$chat_level_discount,2),100,2);
                        }
                    }
                }
            }
            if ($userInfo['balance'] < $chat_price ) {
                $this->worker->clientIdConnections[$connection->client_id]->send(json_encode(['form' => $array['from'], 'type' => 'warning', 'content' => '用户余额不足']));
            }else{
                $userChatModel = new UserChat();
                $userChatInfo = $userChatModel->where(['uid'=>$array['from'],'receive_uid'=>$array['to']])->find();
                $time = time();
                if ($userChatInfo){
                    $userChatModel->where(['uid'=>$array['from'],'receive_uid'=>$array['to']])->update(['create_time' =>$time,'is_remove'=> 0,'update_time' => $time]);
                }else{
                    $userChatModel->insert(['uid'=>$array['from'],'receive_uid'=>$array['to'],'create_time' =>$time,'update_time' => $time]);
                }
                $sendMessage = [
                    'nickname' => $userInfo['nickname'],
                    'avatar' => $userInfo['avatar'],
                    'sex' => $userInfo['sex'],
                    'age' => $userInfo['avatar'],
                    'content' => $array['content'],
                    'to'=> $array['to'],
                    'from'=> $array['from'],
                    'type' => $array['type'],
                    'create_time' => date('Y-d-m H:i',$time),
                ];
                $messageData =[
                    'send_uid' => $array['from'],
                    'receive_uid' => $array['to'],
                    'content' => $array['content'],
                    'create_time' => $time,
                    'type' => $array['type'],
                    'price' => $chat_price,
                    'original_price' => $original_price,
                    'discount' => $chat_level_discount,
                ];
                if (isset( $array['imgWidth'])){
                    $messageData['imgWidth'] =$array['imgWidth'];
                    $sendMessage['imgHeight'] =$array['imgHeight'];
                }
                if (isset( $array['imgHeight'])){
                    $messageData['imgHeight'] =$array['imgHeight'];
                    $sendMessage['imgHeight'] =$array['imgHeight'];
                }
                $sendMessage  = json_encode($sendMessage);
                if ($messageUserClient){ // 发送的用户通道还在
                    if (isset($this->worker->clientIdConnections[$messageUserClient])) { // 用户在聊天页面
                        $messageData['is_read'] = 1;
                        $userMessageModel->insert($messageData);
                        $messageId=$userMessageModel->getLastInsID();
                        $this->worker->clientIdConnections[$messageUserClient]->send($sendMessage);
                    }else{ // 用户已经退出了聊天页
                        $redis->delete('message_'.$array['from'].'_'.$array['to']);
                        $messageData['is_read'] = 0;
                        $userMessageModel->insert($messageData);
                        $messageId=$userMessageModel->getLastInsID();
                        $noticeUserClient = $redis->get('notice_'.$array['to']);
                        if ($noticeUserClient){
                            if (isset($this->worker->clientIdConnections[$noticeUserClient])) { //  推送个用户告诉有消息
                                $this->worker->clientIdConnections[$noticeUserClient]->send($sendMessage);
                            }else{
                                $redis->delete('notice_'.$array['to']);
                            }
                        }
                    }
                }else{
                    $messageData['is_read'] = 0;
                    $userMessageModel->insert($messageData);
                    $messageId=$userMessageModel->getLastInsID();
                    $redis->delete('message_'.$array['to'].'_'.$array['from']);
                    $noticeUserClient = $redis->get('notice_'.$array['to']);
                    if ($noticeUserClient){
                        if (isset($this->worker->clientIdConnections[$noticeUserClient])) { //  推送个用户告诉有消息
                            $this->worker->clientIdConnections[$noticeUserClient]->send($sendMessage);
                        }else{
                            $redis->delete('notice_'.$array['to']);
                        }
                    }
                }
                $userModel->where(['id' => $array['from']])->dec('balance',$chat_price)->update();
                $recharge_ratio  = Config::getConfigValue('recharge_ratio');
                $amountModel = new AmountLog();
                $amountData  = [
                    'uid' =>$array['from'],
                    'amount' => $chat_price,
                    'amount_type' => 1,
                    'amount_direction' => 2,
                    'create_time' => time(),
                    'correlation_id' => $messageId,
                    'operation_source' => 25,
                    'handling_fees_amount' => bcdiv((string)$chat_price,(string)$recharge_ratio,2),
                    'handling_fees' => $chat_price,
                    'original_price' => $original_price,
                ];
                $amountModel->insert($amountData);
            }

        }

    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {

        // 生成一个唯一用户的客户端id
        $client_id = time().rand(100,999);
        // 将生成的client_id赋给当前连接
        $connection->client_id = $client_id;
        // 在当前worker对象中新添属性  保存当前登录的用户的client_id 和 连接对象
        // 以便进行推送
        $this->worker->clientIdConnections[$connection->client_id] = $connection;
        // 将生成的client_id发送给客户端
        $sendMessage  = json_encode(['client_id' => $client_id]);

        $this->worker->clientIdConnections[$connection->client_id]->send($sendMessage);
    }
    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        $redis  = new Redis();
        $userId  = $redis->get('is_online_'.$connection->client_id);
        $redis->delete('is_online_'.$connection->client_id);
        if ($userId){
            $userModel = new User();
            $userModel->where(['id' => $userId])->update(['is_online' => 0]);
        }
        unset($this->worker->clientIdConnections[$connection->client_id]);
        $connection->close();

    }
    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {

    }





}
